unit UBaseModel;

interface

uses Windows, Messages, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Buttons;

type
  IObservavel = interface;

  IObservador = interface
  ['{1F714D8C-2B66-475A-B900-7AA1AF501754}']
    procedure Atualizar(iObservavel: IObservavel);
  end;

  IObservavel = interface
  ['{62350B11-A519-4F58-80EE-C2ABDBCEE6C2}']
    procedure Anexar(iObservador: IObservador);
    procedure Desanexar(iObservador: IObservador);
    procedure Notificar;
  end;

  TBaseObject = class;

  IControle = interface
  ['{2258A118-0EA2-4C5C-8936-A2AF775FE64C}']
    procedure Salvar;
    function Encontrar(sID: String): TBaseObject;
    function Novo: TBaseObject;
  end;

  TBaseObject = class(TInterfacedObject, IObservavel)
    private
      FObservadores: TInterfaceList;
      FId: String;

      procedure SetId(const sId: String);
      function GetId: String;
    public
      constructor Create;
      destructor Destroy; override;

      procedure Anexar(iObservador: IObservador);
      procedure Desanexar(iObservador: IObservador);
      procedure Notificar;

    published
      property xID: String read GetId write SetId;
  end;
implementation

uses ComObj, SysUtils;

{ TBaseObject }

procedure TBaseObject.Anexar(iObservador: IObservador);
begin
  FObservadores.Add(iObservador);
end;

constructor TBaseObject.Create;
  var
    GID: TGUID;
begin
  FObservadores := TInterfaceList.Create;

  //OleCheck(CreateGUID(GID));
  if(CreateGUID(GID) = S_OK)then
  begin
    FId := GUIDToString(GID);
  end;
end;

procedure TBaseObject.Desanexar(iObservador: IObservador);
begin
  FObservadores.Remove(iObservador);
end;

destructor TBaseObject.Destroy;
begin
  FreeAndNil(FObservadores);
end;

function TBaseObject.GetId: String;
begin
  Result := FId;
end;

procedure TBaseObject.Notificar;
  var
    iX: Integer;
begin
  for iX := 0 to FObservadores.Count - 1 do
  begin
    IObservador(FObservadores[iX]).Atualizar(Self);
  end;
end;

procedure TBaseObject.SetId(const sId: String);
begin
  FId := sId;
end;

  // http://delphi.about.com/library/weekly/aa022205a.htm
  // http://www.progtown.com/topic941107-cocreateguid-and-coinitialize.html
  // http://www.devmedia.com.br/criar-guid-em-tempo-de-execucao/16715
  // http://docwiki.embarcadero.com/CodeExamples/XE6/en/UsingGUIDs_%28Delphi%29
  // http://interactiveasp.net/blogs/spgilmore/archive/2009/12/23/using-generics-in-delphi.aspx

end.
